﻿// Lesson18.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include "pch.h"
#include <iostream>
#include <vector>
#include "ConstRect.h"
#include "test.h"
using namespace std;
#include <complex>

#if __has_include(<optional>)
#include<optional>
#elif __has_include(<experimental/optional>)
#include<experimental/optional>
#endif

struct MyStruct
{
	int id;
	int age;
	char name[32];
	int sex;
};

typedef MyStruct* PMyStruct;

typedef int INT;
typedef std::string STR;

typedef std::vector<int> IntVec;

using IntPtr = int *;

using IntVecIter =  std::vector<int>::iterator ;

int func(int a)
{
	std::cout << "func called:"<<a << std::endl;
	return 0;
}

typedef int (*pFunc)(int);

using FuncPtr = int(*)(int);

void FuncCaller(FuncPtr fc,int c)
{
	if (fc)
	{
		fc(c);
	}
}

[[noreturn]] void TerminateMyProcess()
{
	std::exit(1);
}

//[[deprecated]]
bool isDongleAvailable()
{
	bool isAvailable = false;
	return isAvailable;
}


bool isFeatureLicensed(int Appid)
{
	if (isDongleAvailable())
	{
		TerminateMyProcess();
	}
	else
	{
		bool isLicensed = false;
		return isLicensed;
	}
}

//void fun();

constexpr int getArea()
{
	return /*81*/ 9 * 9;//9行和9列的棋盘
}

const std::string& getString()
{
	return "abc";
}

std::pair<std::vector<int>, std::vector<int> > separateOddsAndEvens(std::vector<int> vecUnSplit)
{
	std::pair<std::vector<int>, std::vector<int> > res;
	for (size_t i = 0; i < vecUnSplit.size(); i++)
	{
		if (vecUnSplit[i] % 2 == 1)
		{
			res.first.push_back(vecUnSplit[i]);
		}
		else
		{
			res.second.push_back(vecUnSplit[i]);
		}
	}
	return res;
}

//将数组中的奇数和欧树分开
void separateOddsAndEvens(const int arr[], size_t size, int*& odds, size_t& numOdds, int*& evens, size_t& numEvens)
{
	for (size_t i = 0; i < size; i++)
	{
		if (arr[i] % 2 == 1)
		{
			++numOdds;
		}
		else
		{
			++numEvens;
		}
	}

	odds = new int[numOdds];
	evens = new int[numEvens];

	int oddPos = 0, evenPos = 0;
	for (size_t i = 0; i < size; i++)
	{
		if (arr[i] % 2 == 1)
		{
			odds[oddPos]=arr[i];
			oddPos++;
		}
		else
		{
			evens[evenPos] = arr[i];
			evenPos++;
		}
	}
}

class RefClass
{
public:
	RefClass(int x)
		:xRef(x)
	{

	}

	int& GetMemRef()
	{
		return xRef;
	}
public:
	int xRef;
};

int x;

class Employee
{
public:
	void Test(int a)
	{
		std::cout << "Employee Test:"<<a <<std::endl;
	}

	void SetX(int x)
	{
		::x	= x;
	}
};

typedef void (Employee::* pmemfun)(int);

using upmemfunc = void (Employee::*)(int);

namespace NS1
{
	void test()
	{
		std::cout << "NS1" << std::endl;
	}
}

namespace NS2
{
	void test(int)
	{
		std::cout << "NS2" << std::endl;
	}
}

[[nodiscard]]int func2019()
{
	return 32;
}


//熟模式
//std::complex<long double> operator"" _i(long double d)
//{
//	return std::complex<long double>(0, d);
//}

std::string operator"" _s(const char* str, size_t len)
{
	return std::string(str, len);
}

//生模式
std::complex<long double> operator"" _i(const char* pstr)
{
	return std::complex<long double>(0,std::stod(pstr));
}


int main()
{
	std::string strx = "Hello World"_s;

	auto cx = 1.58_i;

	pmemfun memfunc = &Employee::Test;

	Employee emplyee;

	(emplyee.*memfunc)(2);

	upmemfunc memfunc2 = &Employee::Test;

	bool isLiced = isFeatureLicensed(42);

	(emplyee.*memfunc2)(99);

	using namespace NS2;
	using namespace NS1;
	test();

	for (size_t i = 0; i < 5; i++)
	{
		std::cout << "i="<<i << std::endl;
	}

	int switch_on = 4;

	switch (switch_on)
	{
	case 1:
		func2019();
	case 2:
	{
		break;
	}
	case 3:
		test();
	//[[fallthrough]];
	case 4:
		test(2);
	}


	int x = 5,y=12;
	int& xRef = x;
	int& yRef = y;
	
	xRef = yRef;

	int* pXRef = &xRef;
	pXRef = &yRef;

	*pXRef = 6;

	//std::cout << "x=" << x << ",y=" << y << std::endl;

	xRef = 15;
	//int& xDeclRef;

	//const int& cRef = 5;

	int const& cRef2 = 10;

	//std::cout << "x="<< x << ",y="<< y << std::endl;

	//指向指针的引用

	int* p;
	int*& pRef = p;

	pRef = new int;
	*pRef = 9;

	int xx = 10;
	int& xxRef = xx;
	int* ptrRef = &xxRef;
	int* ptrXX = &xx;

	*ptrRef = 9;


	int xy = 9;

	int * pXY = &xy;

	int xycopy = *pXY;

	int& xyref = *pXY;

	RefClass rc(xyref);

	RefClass& refRC = rc;

	refRC.GetMemRef();

	rc.xRef;

	RefClass* pRC = &rc;
	pRC->GetMemRef();

	//Base* pBase = new Derived();

	//Base& refBase = derivedObj;

	//refBase.virFunc();

	//std::cout << "refmem="<<rc.xRef<<",xy="<<xy << std::endl;

	int unSplit[] = {1,2,5,4,6,7,11,9,22,35,17};
	int* pOdd = nullptr;
	int* pEvens = nullptr;
	size_t numOdd = 0,numEven=0;
	separateOddsAndEvens(unSplit, std::size(unSplit),pOdd,numOdd,pEvens,numEven);

	delete[] pOdd;
	pOdd = nullptr;
	delete[] pEvens;
	pEvens = nullptr;


	std::vector<int> inputArr = { 1,2,5,4,6,7,11,9,22,35,17 };

	auto[odds, evens] = separateOddsAndEvens(inputArr);


	const double PI = 3.14159265359;

	//int* ip = new int[10];
	//ip[1] = 1;

	//不能修改指针所指向的内容
	//int const* ip;
	//ip = new int[10];
	//ip[3] = 3;
	//ip = new int[2];

	//不能修改指针的指向，但是能修改指针指向的内容
	//int* const ip = new int[5] {1,2,3,4,5};

	//ip[2] = 2019;

	//ip = new int[6];

	//既不能，又不能
	int const* const ip = new int[6]{1,2,3,4,5,6};

	constexpr ConstRect cr(9, 9);
	int area[cr.getArea()];

	

	//fun();


	extern int xvalue;

	xvalue = 2019;

	MyStruct* pStu = (MyStruct*)malloc(sizeof(MyStruct));

	IntPtr pInt = new int;
	*pInt = 3;

	std::vector<int> ivec;

	typedef std::vector<std::string> StrVec;
	StrVec strings;
	strings.push_back("abc");
	
	IntVecIter it = ivec.begin();

	using WSTR = std::wstring;

	WSTR wstr = L"ABC";

	pFunc pfun = func;

	pfun(2);

	FuncPtr pfun2 = func;

	FuncCaller(pfun2, 5);

	auto myStr = "Hello,World"s;

	return 0;
}

// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门提示: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件，或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来，若要再次打开此项目，请转到“文件”>“打开”>“项目”并选择 .sln 文件
